package org.jetlinks.protocol.official.mqtt.up.radar60SP;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.jetlinks.core.Value;
import org.jetlinks.core.device.DeviceOperator;
import org.jetlinks.core.message.DeviceMessage;
import org.jetlinks.core.message.codec.MqttMessage;
import org.jetlinks.core.message.function.FunctionInvokeMessageReply;
import org.jetlinks.core.message.property.ReportPropertyMessage;
import org.jetlinks.protocol.official.ObjectMappers;
import org.jetlinks.protocol.official.TopicPayload;
import org.jetlinks.protocol.official.mqtt.down.CacheKeyEnum;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;

import java.util.Map;
import java.util.Optional;

/**
 * @Author bingzhong
 * @Date 2024/12/30 18:07
 * @Description 人体睡眠雷达检测
 * example: /Radar60SP/701D080967EE/sys/property/post
 */
@Slf4j
public class Radar60BreathSleepUpHandler {

    static ObjectMapper mapper = ObjectMappers.JSON_MAPPER;

    @SneakyThrows
    public static Publisher<DeviceMessage> doDecode(MqttMessage message, DeviceOperator deviceOperator) {

        TopicPayload topicPayload = TopicPayload.of(message.getTopic(), message.payloadAsBytes());

        JSONObject dataJson = mapper.readValue(topicPayload.getPayload(), JSONObject.class);

        String opt = Optional.ofNullable(dataJson.get("opt"))
                              .map(String::valueOf)
                              .orElse("");

        if (Radar60SPStatus.get.name().equalsIgnoreCase(opt) || Radar60SPStatus.set.name().equalsIgnoreCase(opt)) {
            return fromReply2FunctionMessage(message, deviceOperator);
        }

        return fromReport2ReportPropertyMessage(message, dataJson, opt);

    }

    private static Mono<DeviceMessage> fromReport2ReportPropertyMessage(MqttMessage message, JSONObject dataJson, String opt) {
        Map params = (Map) dataJson.get("params");
        JSONObject data = new JSONObject();
        data.put("version", dataJson.get("version"));
        data.put("opt", opt);
        data.put("res", dataJson.get("res"));
        data.putAll(params);
        ReportPropertyMessage reportPropertyMessage = new ReportPropertyMessage();
        reportPropertyMessage.setDeviceId(message.getClientId());
        reportPropertyMessage.setProperties(data);
        return Mono.justOrEmpty(reportPropertyMessage);
    }

    @SneakyThrows
    public static Mono<DeviceMessage> fromReply2FunctionMessage(MqttMessage message, DeviceOperator deviceOperator) {
        String key = CacheKeyEnum.FunctionId_.name() + message.getClientId();
        JSONObject dataJson = mapper.readValue(message.payloadAsBytes(), JSONObject.class);
        return deviceOperator.getConfig(key)
                .defaultIfEmpty(Value.simple("empty"))
                .map(Value::asString)
                .map(messageId -> {
                    FunctionInvokeMessageReply reply = new FunctionInvokeMessageReply();
                    reply.setMessageId(messageId);
                    reply.setDeviceId(message.getClientId());
                    reply.setOutput(dataJson);
                    return reply;
                });

    }


}
